package sk.tuke.android4all.listeners;

import android.content.Context;
import android.graphics.PointF;
import android.util.FloatMath;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Ing. Tibor Fecko on 22.2.2014.
 */
public abstract class SwipeListener implements View.OnTouchListener {
    private final GestureDetector mGestureDetector;
    private static final String TAG = "SwipeListener";
    private static long TIME_TO_CONFIRM = 200L;
	
	private long touchDownStamp = 0;
	private long lastTouchTime = 0;
	private int touchCounter = 0;
    private long lastGestureTime = 0;
    private PointF start = new PointF();
    private float oldDist = 1f;
    private float newDist = 1f;
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;

    public SwipeListener (Context aContext_in){
        mGestureDetector = new GestureDetector(aContext_in, new GestureListener());
    }
    
    public void resetTouchCounter(){
    	touchCounter = 0;
    }
    
    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent event){
            Log.i(TAG, "OnDown");
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent event){
            Log.i("Tag", "DoubleTap");
            onDoubleTapAction(touchCounter -1);
			touchCounter = 0;
			lastTouchTime = 0;
            return true;
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        Log.i(TAG, "Touch");
        // Handle touch events here...
        switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
        	case MotionEvent.ACTION_DOWN:
		           start.set(motionEvent.getX(), motionEvent.getY());
		           Log.d(TAG, "mode=DRAG");
		           mode = DRAG;
		           touchDownStamp = motionEvent.getEventTime();
		           break;
        	case MotionEvent.ACTION_POINTER_DOWN:
        		  float x = motionEvent.getX(0) - motionEvent.getX(1);
        	      float y = motionEvent.getY(0) - motionEvent.getY(1);
		           oldDist = FloatMath.sqrt(x * x + y * y);
		           Log.d(TAG, "oldDist=" + oldDist);
		           if (oldDist > 10f) {
		              //midPoint(mid, motionEvent);
		              mode = ZOOM;
		              Log.d(TAG, "mode=ZOOM");
		           }
		           break;
	        case MotionEvent.ACTION_UP:
	        case MotionEvent.ACTION_POINTER_UP:
	        	mode = NONE;
	        	Log.d(TAG, "mode=NONE");
	        	Log.d(TAG, String.valueOf(motionEvent.getEventTime() - touchDownStamp));
	        	if(motionEvent.getEventTime() - touchDownStamp < 200){
		        	if(lastTouchTime == 0 || lastTouchTime + TIME_TO_CONFIRM < System.currentTimeMillis()){
		    			touchCounter++;
		    			lastTouchTime = System.currentTimeMillis();
		    		}
	        	}
	        	break;
	        case MotionEvent.ACTION_MOVE:
	        		if (mode == ZOOM) {
	        			x = motionEvent.getX(0) - motionEvent.getX(1);
	          	      	y = motionEvent.getY(0) - motionEvent.getY(1);
	          	      	newDist = FloatMath.sqrt(x * x + y * y);
	        			Log.d(TAG, "newDist=" + newDist);
	        			if (newDist > 10f) {
	        				float scale = newDist / oldDist;
	        				Log.d(TAG, "scale= " + scale);
		        			if(scale > 2){onZoomOutAction();}
		        			else if(scale < 0.25) {onZoomInAction();}
		        			//lastGestureTime = System.currentTimeMillis();	
	        			}
	           }
	           break;
        }
        if(mode == ZOOM){
        	return true;
        }else{
        	return mGestureDetector.onTouchEvent(motionEvent);
        }
    }
    	
    public abstract void onDoubleTapAction(int singleTouchCountBefore);
    public abstract void onZoomInAction();
    public abstract void onZoomOutAction();
}

   